/*
 * @Filename: 
 * @Author: ws
 * @Description: 
 * @Date: 2022-11-14 19:25:29
 * @LastEditTime: 2022-11-14 20:43:21
 * @Company: 662
 */
`timescale 1ns / 1ps


module rx_sgmii(
  input   wire        i_clk,
  input   wire        wrclk,
  input   wire        wr_reset,

  input   wire [7:0]  m_axis_rx_tdata,
  input   wire        m_axis_rx_tlast,
  input   wire        m_axis_rx_tuser,
  input   wire        m_axis_rx_tvalid,

  output  reg  [7:0]  o_data_8b,
  output  reg         o_data_8b_en,
  input   wire        i_pkt_data_full
);

  parameter     idle_s    = 3'b0,
                rev_s     = 3'b001,
                discard_s = 3'b010,
                send_s    = 3'b011,
                WAIT_1_S  = 3'b111;
  
  reg           wr_en;
  reg           rd_en;
  reg   [8:0]   din;
  wire  [8:0]   dout;
  wire  [11:0]  data_count;
  reg           din_v;
  wire          dout_v;
  wire          empty;
  reg           wr_en_v;
  reg           rd_en_v;

  reg   [2:0]   rec_stat;
  reg   [2:0]   send_stat;

  always@(posedge wrclk or negedge wr_reset)
  if(!wr_reset)begin
    din   <= 9'b0;
    din_v <=  1'b0;
    wr_en <=  1'b0;
    wr_en_v <=  1'b0;
    rec_stat<=  idle_s;
  end
  else begin
    case(rec_stat)
      idle_s: begin
        wr_en <=  1'b0;
        wr_en_v <=  1'b0;
//        if(data_count[11] == 1'b1)  begin
        if(0)  begin
          if(m_axis_rx_tvalid == 1'b1)begin
            rec_stat  <=  discard_s;
            end
          else begin
            rec_stat  <=  idle_s;
          end
        end
        else begin
          if(m_axis_rx_tvalid == 1'b1)begin
            wr_en   <=  m_axis_rx_tvalid;
            din     <=  {m_axis_rx_tlast,m_axis_rx_tdata};
            rec_stat  <=  rev_s;
          end
          else begin
            rec_stat  <=  idle_s;
          end
        end
      end

      rev_s:  begin
        wr_en   <=  m_axis_rx_tvalid;
        din     <=  {m_axis_rx_tlast,m_axis_rx_tdata};
        if((m_axis_rx_tlast == 1'b1)&&(m_axis_rx_tvalid == 1'b1)) begin
          rec_stat  <=  idle_s;
          din_v   <=  1'b1;
          wr_en_v   <=  1'b1;
        end
        else  begin
          rec_stat  <=  rev_s;
        end
      end

      discard_s:  begin
        wr_en   <=  1'b0;
        if((m_axis_rx_tlast == 1'b1)&&(m_axis_rx_tvalid == 1'b1)) begin
          rec_stat  <=  idle_s;
        end
        else begin
          rec_stat  <=  discard_s;
        end
      end
    endcase
  end

      

  always @(posedge i_clk or negedge wr_reset)begin
    if(!wr_reset)begin
      o_data_8b            <= 8'b0;
      o_data_8b_en         <= 1'b0;
      rd_en                 <= 1'b0;
      send_stat             <= idle_s;
    end
    else begin
      case(send_stat)
        idle_s:begin
          o_data_8b        <= 8'b0;
          o_data_8b_en     <= 1'b0;
          rd_en_v           <= 1'b0;
          if(!empty)begin                   //fifo not empty,transmit frame
            if(!i_pkt_data_full)begin
              rd_en         <= 1'b1;
              send_stat     <= send_s;
            end
            else begin
              rd_en         <= 1'b0;
              send_stat     <= idle_s;
            end 
          end
          else begin                      //fifo is empty,wait at idle
            rd_en           <= 1'b0;
            send_stat       <= idle_s;
          end
        end
        send_s:begin
          o_data_8b        <= dout[7:0];
          o_data_8b_en     <= 1'b1;
          if(dout[8])begin                  //tail
            rd_en           <= 1'b0;
            rd_en_v         <= 1'b1;
            send_stat       <= WAIT_1_S;
          end
          else begin
            rd_en           <= 1'b1;
            rd_en_v         <= 1'b0;
            send_stat       <= send_s;
          end
        end
        WAIT_1_S: begin
          o_data_8b        <= 8'b0;
          o_data_8b_en     <= 1'b0;
          rd_en_v           <= 1'b0;
          send_stat         <= idle_s;
        end
      endcase
    end
  end

    
  asfifo_9b_2048 data_fifo(
    .wr_clk(wrclk),               // input wire wrclk
    .rd_clk(i_clk),               // input wire wrclk
    .rst(~wr_reset),              // input wire srst
    .din(din),                    // input wire [8 : 0] din
    .wr_en(wr_en),                // input wire wr_en
    .rd_en(rd_en),                // input wire rd_en
    .dout(dout),                  // output wire [8 : 0] dout.
    .full(),                      // output wire full
    .empty(),                     // output wire empty
    .wr_data_count(data_count)    // output wire [10 : 0] data_count
  );

  asfifo_1b_256 valid_fifo (
    .wr_clk(wrclk),               // input wire wrclk
    .rd_clk(i_clk),               // input wire wrclk
    .rst(~wr_reset),              // input wire srst
    .din(din_v),                  // input wire [0 : 0] din
    .wr_en(wr_en_v),              // input wire wr_en
    .rd_en(rd_en_v),              // input wire rd_en
    .dout(dout_v),                // output wire [63 : 0] dout
    .full(),                      // output wire full
    .empty(empty)                 // output wire empty
  );

endmodule
